package cn.chiship.framework.docs.biz.controller;


import cn.chiship.framework.common.annotation.SystemOptionAnnotation;
import cn.chiship.framework.common.enums.BusinessTypeEnum;
import cn.chiship.framework.docs.biz.entity.FileCatalogConfig;
import cn.chiship.framework.docs.biz.entity.FileCatalogConfigExample;
import cn.chiship.framework.docs.biz.entity.FileResources;
import cn.chiship.framework.docs.biz.entity.FileResourcesExample;
import cn.chiship.framework.docs.biz.pojo.dto.FileResourcesRenameDto;
import cn.chiship.framework.docs.biz.pojo.dto.OptionRecycleBinDto;
import cn.chiship.framework.docs.biz.pojo.vo.FileResourcesVo;
import cn.chiship.framework.docs.biz.service.FileCatalogConfigService;
import cn.chiship.framework.docs.biz.service.FileResourcesService;
import cn.chiship.framework.docs.core.properties.FileUploadProperties;
import cn.chiship.sdk.cache.vo.CacheUserVO;
import cn.chiship.sdk.core.annotation.Authorization;
import cn.chiship.sdk.core.annotation.NoVerificationAppIdAndKey;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.encryption.Md5Util;
import cn.chiship.sdk.core.enums.HeaderEnum;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.framework.base.BaseController;
import cn.chiship.sdk.framework.base.BaseService;
import cn.chiship.sdk.framework.pojo.vo.PageVo;
import cn.chiship.sdk.framework.util.FrameworkUtil;
import cn.chiship.sdk.framework.util.ServletUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * controller
 *
 * @author lijian
 * @date 2020/4/24
 */
@RestController
@Authorization
@RequestMapping("/fileResources")
@Api(tags = "文件资源")
public class FileResourcesController extends BaseController<FileResources, FileResourcesExample> {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileResourcesController.class);

    private static final String COMMA = ",";
    @Resource
    private FileResourcesService fileResourcesService;

    @Resource
    private FileCatalogConfigService fileCatalogConfigService;

    @Resource
    private FileUploadProperties fileUploadProperties;

    @Override
    public BaseService getService() {
        return fileResourcesService;
    }

    @ApiOperation(value = "获取文件存储方式")
    @GetMapping(value = "/storageLocation")
    public ResponseEntity<BaseResult> storageLocation() {
        return super.responseEntity(BaseResult.ok(fileUploadProperties.getStorageLocation()));
    }


    @ApiOperation(value = "文件资源分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码", defaultValue = "1", dataTypeClass = Long.class, paramType = "query"),
            @ApiImplicitParam(name = "limit", value = "每页条数", defaultValue = "10", dataTypeClass = Long.class, paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序方式", defaultValue = "-gmtModified", dataTypeClass = String.class, paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键字", dataTypeClass = String.class, paramType = "query"),
            @ApiImplicitParam(name = "catalogId", value = "所属文档", defaultValue = "4ca7ed82244d4eb692d91e31fabb3c9f", required = true, dataTypeClass = String.class, paramType = "query"),
    })
    @GetMapping(value = "/page")
    public ResponseEntity<BaseResult> page(
            @RequestParam(required = false, defaultValue = "1", value = "page") Long page,
            @RequestParam(required = false, defaultValue = "", value = "keyword") String keyword,
            @RequestParam(value = "catalogId") String catalogId) {
        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        /**
         * 创造条件
         */
        FileResourcesExample.Criteria criteria = fileResourcesExample.createCriteria();
        criteria
                .andIsDeletedEqualTo(BaseConstants.NO)
                .andCatalogIdEqualTo(catalogId);

        FileCatalogConfigExample fileCatalogConfigExample = new FileCatalogConfigExample();

        FileCatalogConfigExample.Criteria configExampleCriteria = fileCatalogConfigExample.createCriteria();
        configExampleCriteria
                .andIsDeletedEqualTo(BaseConstants.NO)
                .andCatalogPidEqualTo(catalogId);


        if (!StringUtil.isNullOrEmpty(keyword)) {
            criteria.andOriginalFileNameLike(keyword + "%");
            configExampleCriteria.andCatalogNameLike(keyword + "%");
        }

        fileCatalogConfigExample.setOrderByClause("orders asc,is_built_in desc,gmt_modified desc");

        PageVo pageVo = page(fileResourcesExample);
        List<FileResources> fileResources = pageVo.getRecords();
        List<FileResourcesVo> fileResourcesVos = new ArrayList<>();
        if (page == 1L) {
            List<FileCatalogConfig> catalogConfigs = fileCatalogConfigService.selectByExample(fileCatalogConfigExample);
            catalogConfigs.forEach(item -> {
                FileResourcesVo resourcesVo = new FileResourcesVo();
                resourcesVo.setId(item.getId());
                resourcesVo.setGmtCreated(item.getGmtCreated());
                resourcesVo.setGmtModified(item.getGmtModified());
                resourcesVo.setUuid(item.getCatalogUuid());
                resourcesVo.setName(item.getCatalogName());
                resourcesVo.setFile(false);
                resourcesVo.setRealName(item.getRealName());
                resourcesVo.setFileType(Byte.valueOf((item.getCatalogType() * -1) + ""));
                fileResourcesVos.add(resourcesVo);
            });
        }
        fileResources.forEach(item -> {
            FileResourcesVo resourcesVo = new FileResourcesVo();
            resourcesVo.setId(item.getId());
            resourcesVo.setGmtCreated(item.getGmtCreated());
            resourcesVo.setGmtModified(item.getGmtModified());
            resourcesVo.setUuid(item.getFileUuid());
            resourcesVo.setName(item.getOriginalFileName());
            resourcesVo.setFile(true);
            resourcesVo.setRealName(item.getRealName());
            resourcesVo.setFileSize(item.getFileSize());
            resourcesVo.setFileType(item.getFileType());
            resourcesVo.setFileExt(item.getFileExt());
            resourcesVo.setCatalogId(item.getCatalogId());
            resourcesVo.setStorageLocation(item.getStorageLocation());
            fileResourcesVos.add(resourcesVo);
        });
        pageVo.setRecords(fileResourcesVos);
        return super.responseEntity(BaseResult.ok(pageVo));
    }

    @ApiOperation(value = "根据UUID获取文件详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuid", value = "文件标识", dataTypeClass = String.class, paramType = "path", required = true)
    })
    @GetMapping(value = "/getByUUID/{uuid}")
    @NoVerificationAppIdAndKey
    public ResponseEntity<BaseResult> getByUuid(@PathVariable(value = "uuid") String uuid) {
        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        FileResourcesExample.Criteria criteria = fileResourcesExample.createCriteria();
        criteria.andIsDeletedEqualTo(BaseConstants.NO).andFileUuidEqualTo(uuid);
        List<FileResources> fileResources = fileResourcesService.selectByExample(fileResourcesExample);
        return super.responseEntity(fileResources.isEmpty() ? BaseResult.ok() : BaseResult.ok(fileResources.get(0)));
    }

    @ApiOperation(value = "根据UUID获取同文件夹所有图片")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuid", value = "文件标识", dataTypeClass = String.class, paramType = "query", required = true)
    })
    @GetMapping(value = "/listSameFolderFileByUUID")
    @NoVerificationAppIdAndKey
    public ResponseEntity<BaseResult> listSameFolderFileByUUID(@RequestParam(value = "uuid") String uuid) {
        return super.responseEntity(fileResourcesService.listSameFolderFileByUUID(uuid));
    }

    @ApiOperation(value = "添加收藏")
    @PostMapping(value = "/collectionAdd")
    public ResponseEntity<BaseResult> collectionAdd(@RequestBody @Valid String fileId) {
        CacheUserVO userVO = getLoginUser();
        return super.responseEntity(fileResourcesService.collectionAdd(
                ServletUtil.getHeader(HeaderEnum.HEADER_PROJECTS_ID.getName()),
                fileId,
                userVO.getId().toString(),
                userVO.getUsername(),
                userVO.getRealName()
        ));
    }

    @ApiOperation(value = "取消收藏")
    @PostMapping(value = "/collectionCancel")
    public ResponseEntity<BaseResult> collectionCancel(@RequestBody @Valid String fileId) {
        CacheUserVO userVO = getLoginUser();
        return super.responseEntity(fileResourcesService.collectionCancel(
                fileId,
                userVO.getId().toString(),
                userVO.getUsername(),
                userVO.getRealName()
        ));
    }

    @ApiOperation(value = "文件重命名")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键", dataTypeClass = String.class, paramType = "path", required = true)
    })
    @PostMapping(value = "rename/{id}")
    public ResponseEntity<BaseResult> rename(@PathVariable("id") String id,
                                             @RequestBody @Valid FileResourcesRenameDto fileResourcesDto) {
        CacheUserVO userVO = getLoginUser();
        FileResources fileResources = new FileResources();
        BeanUtils.copyProperties(fileResourcesDto, fileResources);
        fileResources.setId(id);
        return super.responseEntity(fileResourcesService.rename(fileResources, userVO.getId().toString(), userVO.getUsername(), userVO.getRealName()), HttpStatus.OK);
    }

    @SystemOptionAnnotation(describe = "回收站文件还原")
    @ApiOperation(value = "回收站文件还原")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键", dataTypeClass = String.class, paramType = "path", required = true)
    })
    @PostMapping(value = "reduction/{id}")
    public ResponseEntity<BaseResult> reduction(@PathVariable("id") String id) {
        return super.responseEntity(fileResourcesService.reduction(id, getLoginUser().getId().toString(), getLoginUser().getUsername(), getLoginUser().getRealName()), HttpStatus.OK);
    }


    @ApiOperation(value = "移入回收站")
    @PostMapping(value = "/moveToRecycleBin")
    public ResponseEntity<BaseResult> moveToRecycleBin(@RequestBody @Valid OptionRecycleBinDto optionRecycleBinDto) {
        CacheUserVO userVO = getLoginUser();
        return super.responseEntity(fileResourcesService.moveToRecycleBin(ServletUtil.getHeader(HeaderEnum.HEADER_PROJECTS_ID.getName()), optionRecycleBinDto.getFileId(), optionRecycleBinDto.getType(), userVO.getId().toString(), userVO.getUsername(), userVO.getRealName()));
    }

    /**
     * 上传组件 自带删除按钮用
     */
    @ApiOperation(value = "删除文件")
    @PostMapping(value = "/removeFile")
    public ResponseEntity<BaseResult> removeFile(@RequestBody @Valid String fileUuid) {
        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        fileResourcesExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO).andFileUuidEqualTo(fileUuid);
        BaseResult baseResult = fileResourcesService.removeFile(fileUuid);
        return super.responseEntity(baseResult);
    }

    @ApiOperation(value = "清空回收站")
    @PostMapping(value = "/clearRecycleBin")
    public ResponseEntity<BaseResult> clearRecycleBin(@RequestBody @Valid OptionRecycleBinDto optionRecycleBinDto) {
        CacheUserVO userVO = getLoginUser();
        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        FileResourcesExample.Criteria criteria = fileResourcesExample.createCriteria().andUserIdEqualTo(userVO.getId().toString());
        if (optionRecycleBinDto.getIsFile() == 1) {
            criteria.andIdEqualTo(optionRecycleBinDto.getFileId());
        } else {
            criteria.andCatalogIdEqualTo(optionRecycleBinDto.getFileId());
        }

        return super.responseEntity(fileResourcesService.deleteByExample(fileResourcesExample));
    }

    @SystemOptionAnnotation(describe = "文件允许删除&不允许删除", option = BusinessTypeEnum.SYSTEM_OPTION_UPDATE)
    @ApiOperation(value = "文件允许删除&不允许删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键", dataTypeClass = String.class, paramType = "path", required = true)
    })
    @PostMapping(value = "changeIsAllowDelete/{id}")
    public ResponseEntity<BaseResult> changeIsAllowDelete(@PathVariable("id") String id,
                                                          @RequestBody Boolean isAllowDelete) {
        CacheUserVO userVO = getLoginUser();
        return super.responseEntity(fileResourcesService.changeIsAllowDelete(isAllowDelete, id, userVO.getId().toString(), userVO.getUsername(), userVO.getRealName()));
    }

    @SystemOptionAnnotation(describe = "验证文件密码")
    @ApiOperation(value = "验证文件密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键", dataTypeClass = String.class, paramType = "path", required = true)
    })
    @PostMapping(value = "checkPassword/{id}")
    public ResponseEntity<BaseResult> checkPassword(@PathVariable("id") String id, @RequestBody String password) {

        FileResources fileResources = fileResourcesService.selectByPrimaryKey(id);

        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        fileResourcesExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO).andIdEqualTo(id).andEncryptionPasswordEqualTo(Md5Util.md5(password + fileResources.getEncryptionSalt()));

        List<FileResources> fileResourcesList = fileResourcesService.selectByExample(fileResourcesExample);
        if (fileResourcesList.isEmpty()) {
            return super.responseEntity(BaseResult.error("密码错误"));
        }
        return super.responseEntity(BaseResult.ok(true));
    }
    @ApiOperation(value = "根据UUID集合获取详情 ")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuids", value = "UUID集合", required = true, dataType = "String", paramType = "query")
    })
    @GetMapping("/listByUUID")
    public ResponseEntity<BaseResult> mergeFile(@RequestParam(value = "uuids") String uuids) {
        if (StringUtil.strToListString(uuids, COMMA).isEmpty()) {
            return super.responseEntity(BaseResult.ok(new ArrayList<>()));
        }
        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        fileResourcesExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO).andFileUuidIn(StringUtil.strToListString(uuids, ","));
        List<FileResources> fileResourcesList = fileResourcesService.selectByExample(fileResourcesExample);
        fileResourcesExample.setOrderByClause(FrameworkUtil.formatSort("-gmtCreated"));
        return super.responseEntity(BaseResult.ok(fileResourcesList));
    }
}
